const WebSocket = require('ws');
const ws = new WebSocket.Server({ port: 3001 });

let subjects = {}
let wss = {}
let subject_ws_map = {}

// 订阅
function subscribe(subject, ws,id) {
  subjects[id] = subject
  wss[id] = ws
  if(subject_ws_map[subject]){
    subject_ws_map[subject].push(id)
  } else {
    subject_ws_map[subject] = [id]
  }
}

// 取消订阅
function unsubscribe(ws,id) {
  let subject = subjects[id]
  delete subjects[id]
  delete wss[id]
  if(subject_ws_map[subject] && subject_ws_map[subject].length){
    let index = subject_ws_map[subject].indexOf(id)
    subject_ws_map[subject].splice(index,1)
  }
  
}

// 向某个主题发布事件
function publish(subject, event, data, exclude,excludeid) {
  if (!subject_ws_map[subject] && subject_ws_map[subject].length) {
      return;
  }
  console.log(subject_ws_map[subject].length)
  subject_ws_map[subject].forEach(id =>{
    if(id !== excludeid){
      let ws = wss[id]
      ws && ws.send(
        JSON.stringify({
          'cmd':'publish',
          'event': event,
          'data': data
        })
      )
    }
  })
}
function getUUID () {
  return new Date().getTime()
}
ws.on('connection', ws => {
  console.log('server connection');
  const id = getUUID();
  ws.on('message', msg => {
    console.log('server receive msg：', msg);
    let data = JSON.parse(msg);
    let subject = data.subject 
    switch (data.cmd) {
        // 订阅主题
        case 'subscribe':
            subscribe(subject, ws,id);
            break;
        // 向某个主题发布消息
        case 'publish':
            let event = data.event;
            let d = data.data;
            publish(subject, event, d, ws,id);
            break;
    }
  });
  // ws.send('Information from the server');
  ws.on('close',() => {
    unsubscribe(ws,id)
  })
});